package com.atguigu.tingshu.user.listener;

import com.alibaba.fastjson.JSON;
import com.atguigu.tingshu.album.client.TrackInfoFeignClient;
import com.atguigu.tingshu.common.constant.RabbitConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.user.*;
import com.atguigu.tingshu.user.mapper.*;
import com.atguigu.tingshu.vo.user.UserPaidRecordVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.rabbitmq.client.Channel;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalDate;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

@Component
public class UserListener {

    @Autowired
    private UserVipServiceMapper userVipServiceMapper;

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Autowired
    private VipServiceConfigMapper vipServiceConfigMapper;

    @Autowired
    private UserPaidAlbumMapper userPaidAlbumMapper;

    @Autowired
    private UserPaidTrackMapper userPaidTrackMapper;

    @Autowired
    private TrackInfoFeignClient trackInfoFeignClient;

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(RabbitConstant.USER_RECORD_QUEUE),
            exchange = @Exchange(value = RabbitConstant.ORDER_EXCHANGE, type = ExchangeTypes.TOPIC, ignoreDeclarationExceptions = "true"),
            key = RabbitConstant.USER_RECORD_RK
    ))
    public void userPaidRecord(String json, Channel channel, Message message) throws IOException {
        if (StringUtils.isBlank(json)){
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            return;
        }
        // 反序列化实体类对象
        UserPaidRecordVo recordVo = JSON.parseObject(json, UserPaidRecordVo.class);
        if (recordVo == null){
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            return;
        }

        // 获取vo中的参数
        String orderNo = recordVo.getOrderNo();
        Long userId = recordVo.getUserId();
        List<Long> itemIdList = recordVo.getItemIdList();

        // 判断订单类型
        switch (recordVo.getItemType()){
            case SystemConstant.ORDER_ITEM_TYPE_ALBUM: // 专辑订单

                // 查询同一个订单编号有没有记录过
                UserPaidAlbum userPaidAlbum = this.userPaidAlbumMapper.selectOne(new LambdaQueryWrapper<UserPaidAlbum>().eq(UserPaidAlbum::getOrderNo, orderNo));
                if (userPaidAlbum != null){
                    channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                    return;
                }

                // 新增专辑的购买记录
                userPaidAlbum = new UserPaidAlbum();
                userPaidAlbum.setOrderNo(orderNo);
                userPaidAlbum.setUserId(userId);
                userPaidAlbum.setAlbumId(itemIdList.get(0));
                this.userPaidAlbumMapper.insert(userPaidAlbum);

                // TODO：发送消息给RabbitMQ，给专辑累加购买次数

                break;
            case SystemConstant.ORDER_ITEM_TYPE_TRACK: // 声音订单
                // 查询同一个订单是否已记录过
                Long count = this.userPaidTrackMapper.selectCount(new LambdaQueryWrapper<UserPaidTrack>().eq(UserPaidTrack::getOrderNo, orderNo));
                if (count > 0){
                    channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                    return;
                }

                // 根据第一个声音的id查询声音
                Result<TrackInfo> trackInfoResult = this.trackInfoFeignClient.getTrackInfo(itemIdList.get(0));
                Assert.notNull(trackInfoResult, "记录声音的购买行为时，获取声音信息失败！");
                TrackInfo trackInfo = trackInfoResult.getData();

                // 新增购买记录
                itemIdList.forEach(trackId -> {
                    UserPaidTrack userPaidTrack = new UserPaidTrack();
                    userPaidTrack.setOrderNo(orderNo);
                    userPaidTrack.setUserId(userId);
                    userPaidTrack.setTrackId(trackId);
                    userPaidTrack.setAlbumId(trackInfo.getAlbumId());
                    this.userPaidTrackMapper.insert(userPaidTrack);
                });

                // TODO：发送消息给MQ，记录专辑和声音的购买统计

                break;
            case SystemConstant.ORDER_ITEM_TYPE_VIP:  // vip订单
                // 幂等性操作
                UserVipService userVipService = this.userVipServiceMapper.selectOne(new LambdaQueryWrapper<UserVipService>().eq(UserVipService::getOrderNo, orderNo));
                if (userVipService != null){ // 如果存在该订单编号对应的记录则说明已记录过了
                    channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                    return;
                }
                // 获取本次购买vip套餐
                VipServiceConfig vipServiceConfig = this.vipServiceConfigMapper.selectById(itemIdList.get(0));
                // 更新用户表中的vip状态及过期时间
                UserInfo userInfo = this.userInfoMapper.selectById(userId);
                // 获取vip明细的起始时间
                LocalDate startTime = LocalDate.now();
                LocalDate newExpireTime = null;
                // 如果是未过期vip
                if (userInfo.getIsVip().intValue() == 1 && userInfo.getVipExpireTime().after(new Date())){
                    // 获取现有的vip过期时间
                    LocalDate expireTime = LocalDate.fromDateFields(userInfo.getVipExpireTime());
                    startTime = expireTime.plusDays(1);
                    // 累加vip套餐的服务月份
                    newExpireTime = expireTime.plusMonths(vipServiceConfig.getServiceMonth());
                    userInfo.setVipExpireTime(newExpireTime.toDate());
                } else {
                    // 如果不是未过期的vip，则更新为vip状态
                    userInfo.setIsVip(1);
                    // 今天累加vip的服务月份
                    newExpireTime = LocalDate.now().plusMonths(vipServiceConfig.getServiceMonth()).minusDays(1);
                    userInfo.setVipExpireTime(newExpireTime.toDate());
                }
                this.userInfoMapper.updateById(userInfo);

                // 新增vip的购买明细
                userVipService = new UserVipService();
                userVipService.setOrderNo(orderNo);
                userVipService.setUserId(userId);
                userVipService.setStartTime(startTime.toDate());
                userVipService.setExpireTime(newExpireTime.toDate());
                this.userVipServiceMapper.insert(userVipService);

                break;
        }
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    }

    public static void main(String[] args) {
        System.out.println(LocalDate.now().plusMonths(12).minusDays(1).toDate());
    }
}
